<!DOCTYPE html>
<html>
<head>
    <title>Mass-Spring System</title>
</head>
<body>
    <canvas id="physicsCanvas" width="450" height="450"></canvas>
    <script>
        const canvas = document.getElementById('physicsCanvas');
        const ctx = canvas.getContext('2d');

        // Style settings
        ctx.lineWidth = 1.5;
        ctx.strokeStyle = 'black';
        ctx.fillStyle = 'black';
        ctx.font = '22px Arial';
        ctx.textAlign = 'start';
        ctx.textBaseline = 'middle';

        // Parameters
        const centerX = canvas.width / 2; // 225
        const supportY = 60;
        const supportWidth = 200;
        const massWidth = 90;
        const massHeight = 45;
        const lIndicatorX = 350;

        // Spring parameters
        const springTopY = supportY;
        const springTopStraightLength = 25;
        const springBottomStraightLength = 25;
        const helixStartY = springTopY + springTopStraightLength; // 85
        const massTopY = 280;
        const springBottomY = massTopY; // 280
        const helixEndY = springBottomY - springBottomStraightLength; // 255
        const helixHeight = helixEndY - helixStartY; // 170
        const coilRadius = 22;
        const numCoils = 9;

        // Mass derived parameters
        const massBottomY = massTopY + massHeight; // 325
        const massLeftX = centerX - massWidth / 2; // 180
        const massRightX = centerX + massWidth / 2; // 270

        // --- Drawing Function for Arrowheads ---
        function drawArrowhead(ctx, fromX, fromY, toX, toY) {
            const headlen = 8;
            const dx = toX - fromX;
            const dy = toY - fromY;
            const angle = Math.atan2(dy, dx);
            ctx.beginPath();
            ctx.moveTo(toX, toY);
            ctx.lineTo(toX - headlen * Math.cos(angle - Math.PI / 6), toY - headlen * Math.sin(angle - Math.PI / 6));
            ctx.moveTo(toX, toY);
            ctx.lineTo(toX - headlen * Math.cos(angle + Math.PI / 6), toY - headlen * Math.sin(angle + Math.PI / 6));
            ctx.stroke();
        }

        // --- Draw Components ---

        // 1. Draw the support
        ctx.beginPath();
        ctx.moveTo(centerX - supportWidth / 2, supportY);
        ctx.lineTo(centerX + supportWidth / 2, supportY);
        ctx.stroke();

        // Draw hatching for the support ( \ direction)
        const hatchLength = 10;
        const hatchSpacing = 18;
        for (let x = centerX - supportWidth / 2 + hatchLength; x <= centerX + supportWidth / 2; x += hatchSpacing) {
            ctx.beginPath();
            ctx.moveTo(x, supportY);
            ctx.lineTo(x - hatchLength, supportY - hatchLength);
            ctx.stroke();
        }

        // 2. Draw the spring
        ctx.beginPath();
        ctx.moveTo(centerX, springTopY);
        ctx.lineTo(centerX, helixStartY); // Top straight part

        const numSegments = numCoils * 20; // for smoothness
        for (let i = 0; i <= numSegments; i++) {
            const y_ratio = i / numSegments;
            const y = helixStartY + y_ratio * helixHeight;
            const angle = y_ratio * numCoils * 2 * Math.PI;
            const x = centerX + coilRadius * Math.sin(angle);
            ctx.lineTo(x, y);
        }
        
        ctx.lineTo(centerX, springBottomY); // Bottom straight part
        ctx.stroke();

        // 3. Draw the mass
        ctx.beginPath();
        ctx.rect(massLeftX, massTopY, massWidth, massHeight);
        ctx.stroke();

        // 4. Draw labels and pointers
        ctx.font = '22px Arial';

        // Label "spring"
        const springLabelY = helixStartY + helixHeight / 2;
        ctx.fillText('spring', 80, springLabelY);
        ctx.beginPath();
        ctx.moveTo(142, springLabelY);
        ctx.lineTo(centerX - coilRadius - 5, springLabelY);
        ctx.stroke();

        // Label "mass M"
        const massLabelY = massTopY + massHeight / 2;
        ctx.fillText('mass M', 70, massLabelY);
        ctx.beginPath();
        ctx.moveTo(145, massLabelY);
        ctx.lineTo(massLeftX, massLabelY);
        ctx.stroke();

        // 5. Draw the length indicator 'L'
        // Dashed line from mass
        ctx.save();
        ctx.setLineDash([5, 3]);
        ctx.beginPath();
        ctx.moveTo(massRightX, massBottomY);
        ctx.lineTo(lIndicatorX, massBottomY);
        ctx.stroke();
        ctx.restore();

        // Vertical line for L
        ctx.beginPath();
        ctx.moveTo(lIndicatorX, supportY);
        ctx.lineTo(lIndicatorX, massBottomY);
        ctx.stroke();

        // Arrowheads for L
        drawArrowhead(ctx, lIndicatorX, supportY + 10, lIndicatorX, supportY);
        drawArrowhead(ctx, lIndicatorX, massBottomY - 10, lIndicatorX, massBottomY);

        // Label 'L'
        ctx.font = 'italic 22px Arial';
        ctx.fillText('L', lIndicatorX + 15, (supportY + massBottomY) / 2);

        // 6. Draw the caption
        ctx.font = 'bold 20px Arial';
        ctx.textAlign = 'center';
        ctx.fillText('Fig. 3.1', centerX, canvas.height - 30);

    </script>
</body>
</html>